<template>
 <div id="box">
   <el-dialog :title="resetForm.state ? '重置属性' : '新建表单'" :visible.sync="newForm.visible" :before-close="handleClose">
     <div class="lab">输入表单名称:</div>
     <el-input v-if="!resetForm.state" v-model.trim="newForm.name" placeholder="输入表单名称"></el-input>
     <el-input v-if="editableTabs.length > 0 && resetForm.state" v-model.trim="editableTabs[resetForm.index].title" placeholder="输入表单名称"></el-input>
     <div class="lab">选中表单类型:</div>
     <el-select @change="selectObj($event)" v-if="!resetForm.state" filterable v-model="newForm.value">
       <el-option v-for="(v, k) in newForm.options" :key="k" :label="v.label" :value="v.value"></el-option>
     </el-select>
     <el-select @change="selectObj($event)" v-if="editableTabs.length > 0 && resetForm.state" filterable v-model="editableTabs[resetForm.index].value">
       <el-option v-for="(v, k) in newForm.options" :key="k" :label="v.label" :value="v.value"></el-option>
     </el-select>
     <el-collapse accordion v-if="hasTmpls">
       <el-collapse-item>
        <template slot="title">
          默认模板<i class="header-icon el-icon-info" @click.stop="tips"></i>
        </template>
        <el-radio-group v-model="businessChoise">
          <el-radio v-for="(v, k) in businessList" :key="k" :label="v.value">{{v.label}}</el-radio>
        </el-radio-group>
      </el-collapse-item>
     </el-collapse>
     <nonce :formlist="editableTabs"></nonce>
     <div slot="footer" class="dialog-footer">
      <el-button @click="newForm.visible = false">取 消</el-button>
      <el-button v-if="!resetForm.state" type="primary" @click="mkdirForm">确 定</el-button>
      <el-button v-else type="success" @click="resetVal">确 定</el-button>
     </div>
   </el-dialog>
   <!---->
   <el-tabs
    v-if="editableTabs.length > 0"
    v-model="indexTab"
    type="card"
    editable
    @edit="handleTab"
    @tab-click="tabclick"
   >
     <el-tab-pane
       ref="tabitems"
       v-for="(item, index) in editableTabs"
       :key="index"
       :label="item.title"
       :name="item.name"
     >
        <edit ref="edit" v-if="editableTabs.length > 0" :formCom="indexForm_Coms" :indexTap="indexTab" :config="businessChoise"></edit>
     </el-tab-pane>
   </el-tabs>
  <div class="save" v-if="!newForm.visible">
    <el-button type="danger" size="small" @click="preView">预览</el-button>
    <el-button type="primary" size="small" @click="saveForm">保存</el-button>
  </div>
 </div>
</template>
<script>
/**
 * @author 'yejinbo'
 * @description `选择业务对象时的弹窗`
 */
import edit from 'com/edit'
import { INDEXTAP } from '@/store/types'
import nonce from 'com/nonce'
import _S from '@/config/s'
import { mapState } from 'vuex'
import extend from 'lodash/extend'
export default {
  data () {
    return {
      indexTab: '1', // 判断当前是哪个标签页
      indexForm_Coms: [], // 当前标签页都有什么元素(组件)
      editableTabs: [], //  存放所有标签页
      pkid: '', // 保存的时候，如果pkid存在则是编辑，不存在则是新增，该值由后端提供，在新增时就会返回一个pkid，代表当前表单
      hasTmpls: false, // 一个flag，判断是否有模板存在
      businessList: [ //  所有模板的渲染数据
        {
          label: 'test1',
          value: 'test1'
        },
        {
          label: 'test2',
          value: 'test2'
        }
      ],
      businessChoise: '', //  选择的模板
      newForm: {
        name: '', //  新增表单名字
        visible: false, // 弹窗可视化的状态
        value: '', // 新增表单的对应字段
        options: [ //  表单的可选对象字段,对象字段指后端提供的组件之下的对象
          {
            label: '业务1',
            value: 'formA'
          },
          {
            label: '业务2',
            value: 'formB'
          },
          {
            label: '业务3',
            value: 'formC'
          }
        ]
      },
      resetForm: { //  重置表单
        state: false, //  重置的状态
        index: '' //  一个重置的索引
      }
    }
  },
  computed: {
    now () { // 判断当前是哪一张表单的索引，没有用到...
      let _index = null
      if (!this.editableTabs || !(this.editableTabs.length > 0)) return 0
      for (let [k, v] of this.editableTabs.entries()) {
        if (v.name === this.indexTab) {
          _index = k
          break
        }
      }
      return _index
    },
    ...mapState(['indexPath'])
  },
  watch: {
    //  判断当前tab页数，如果增加就给个事件，允许在进行右键点击的时候重新选中业务对象
    'editableTabs.length': function (nv, ov) {
      if (nv > 0) {
        this.$nextTick(() => {
          if (nv > ov) {
            let tabs = document.getElementsByClassName('el-tabs__item')
            let _this = this
            this.$drag(tabs.length - 1)
            tabs[tabs.length - 1].addEventListener('contextmenu', function (e) {
              e = e || window.event
              let tabitems = _this.$refs.tabitems
              for (let i = 0, l = tabitems.length; i < l; i++) {
                if (tabs[i] === this && /is-active/g.test(this.className)) {
                  _this.resetForm.state = true
                  _this.resetForm.index = i
                  _this.newForm.visible = true
                  _this.$forceUpdate()
                  break
                }
              }
              e.returnValue = false
              return false
            }, false)
          }
        })
      }
    },
    //  判断当前处于哪一个tab页，然后更新这个tab页的数据
    indexTab (nv) {
      for (let [k, v] of this.editableTabs.entries()) {
        if (v.name === nv) {
          this.$store.dispatch(INDEXTAP, this.editableTabs[k])
          for (let [ki, vi] of this.newForm.options.entries()) {
            if (this.editableTabs[k].value === vi.value) {
              if (!vi.children) {
                this.$store.dispatch('fetchComFields', {
                  beanname: this.editableTabs[k].value,
                  userToken: 'admin'
                }).then(data => {
                  this.newForm.options[ki].children = data.data
                  this.$nextTick().then(() => {
                    this.indexForm_Coms = vi.children
                  })
                })
              } else {
                this.$nextTick().then(() => {
                  this.indexForm_Coms = vi.children
                })
              }
            }
          }
        }
      }
    },
    //  当弹窗出现就去请求判断是否有模板的
    'newForm.visible': function (nv) {
      if (nv === true) {
        this.$store.dispatch('fetchTmpls', {queryName: 'queryList', userToken: 'admin'}).then(res => {
          if (!Array.isArray(res.data) || !res.data.length) {
            this.hasTmpls = false
          } else {
            this.businessList = []
            for (let v of res.data) this.businessList.push(v)
            this.hasTmpls = true
            this.$forceUpdate()
          }
        }).catch(err => {
          return new Error(err)
        })
      }
    }
  },
  methods: {
    //  关闭弹窗
    handleClose () {
      this.newForm.visible = false
      this.resetForm.state = false
    },
    //  用户点击确定时的生成表单事件
    mkdirForm () {
      if (!this.newForm.name || !this.newForm.value) {
        return this.$notify.warning('您有表单项未选！')
      }
      let _id = Date.now() + ''
      let newFormConfig = {
        title: this.newForm.name,
        value: this.newForm.value,
        name: _id, //  将这个时间戳存起来，作为表单的索引
        business: `${this.newForm.value}-${_id}` //  存放组合
      }
      this.editableTabs.push(newFormConfig) //  push进当前的表单列表中
      this.indexTab = newFormConfig.name
      for (let [k, v] of this.newForm.options.entries()) {
        if (v.value === newFormConfig.value) {
          this.newForm.options[k]['formid'] = newFormConfig.name //  设置这个tan的标识id(只在前端有用)
        }
      }
      this.newForm.visible = false
    },
    //  用户点击确定时重选业务对象的事件
    resetVal () {
      this.resetForm.state = false
      if (!this.newForm.name || !this.newForm.value) {
        return this.$notify.warning('您有表单项未选！')
      }
      let _v = this.editableTabs[this.resetForm.index].value
      let _t = this.editableTabs[this.resetForm.index].business.split('-')
      if (_t[0] === _v) {
        this.newForm.visible = false
        return
      }
      _t[0] = _v
      //  不再生成时间戳,需将表单的id分割一下
      this.editableTabs[this.resetForm.index].business = _t.join('-')
      //  判断当前tab页是不是当前表单页
      if (this.indexTab === this.editableTabs[this.resetForm.index].name) {
        //  跟新一下Vuex当前的tab页
        this.$store.dispatch(INDEXTAP, this.editableTabs[this.resetForm.index])
      }
      for (let [ki, vi] of this.newForm.options.entries()) {
        //  重新拉取数据
        if (vi.value === this.editableTabs[this.resetForm.index].value) {
          if (!vi.children) {
            this.$store.dispatch('fetchComFields', {
              beanname: this.editableTabs[this.resetForm.index].value,
              userToken: 'admin'
            }).then(data => {
              this.newForm.options[ki].children = data.data
              this.$nextTick().then(() => {
                this.indexForm_Coms = vi.children
              })
            })
          } else {
            this.$nextTick().then(() => {
              this.indexForm_Coms = vi.children
            })
          }
        }
      }
      this.newForm.visible = false
      // 提交事件，通知跟新组件内一些状态
      _S.$emit('updateComs')
    },
    //  这个暂时没用到,判断是不是新增表单
    handleTab (targetName, action) {
      if (action === 'add') {
        //  判断是不是创建
        if (this.move === 'mkdir') {
          this.newForm.visible = true
        }
      }
      if (action === 'remove') {
        this.$confirm('关闭后您所做的任何操作将不会被保存，是否关闭?').then(() => {
          this.resetForm.state = false
          let tabs = this.editableTabs
          let activeName = ''
          tabs.forEach((tab, index) => {
            if (tab.name === targetName) {
              let nextTab = tabs[index + 1] || tabs[index - 1]
              if (nextTab) {
                activeName = nextTab.name
              }
            }
          })
          this.indexTab = activeName
          this.editableTabs = tabs.filter(tab => tab.name !== targetName)
        }).catch((_) => {
        })
      }
    },
    tabclick (tab) {
    },
    tips () {
      this.$message('你可以通过勾选选择模板')
    },
    selectObj (v) {
    },
    // 生成符合后端模板的单表单数据
    converForm (conf) {
      conf.form = {
        orgId: conf.orgId,
        id: null,
        compId: conf.compId,
        title: conf.desName,
        beanId: conf.beanId,
        colsInOneRow: 2,
        formName: conf.desName
      }
      let o = Object.create(null)
      o = {
        compId: conf.compId,
        orgId: conf.orgId,
        beanId: conf.beanId,
        cols: 1,
        rows: 1,
        form: null,
        idField: 'false',
        align: 'center',
        aid: '',
        type: 'default',
        id: '',
        dataUrl: '',
        refBean: null,
        formId: conf.desCode,
        hidden: false,
        grid: null
      }
      let p = Promise.resolve()
      p.then(() => {
        for (let edit of this.$refs.edit) {
          for (let [index, com] of edit.vNodes.entries()) {
            if (!com.mine.value) {
              return this.$notify.error({
                dangerouslyUseHTMLString: true,
                message: `<strong>表单中第<span style="color: red">${index + 1}</span>个元素的字段未选择</strong>`
              })
            }
            let _o = Object.create(null)
            _o = {
              cols: com.mine.cols,
              rows: com.mine.rows,
              align: com.mine.align,
              orderNum: index,
              type: com.attrs.type,
              dataUrl: com.mine.dataUrl,
              hidden: com.mine.hidden,
              readonly: com.mine.readonly,
              name: com.mine.describe,
              showType: com.elname,
              required: com.mine.isneed,
              attrName: com.mine.value
            }
            let a = extend(o, _o)
            a = JSON.parse(JSON.stringify(a))
            conf.attributes.push(a)
          }
        }
        console.log('save now')
        this.saveMaster(conf)
      })
    },
    converConfig () {
      this.$nextTick(() => {
        const conf = {
          orgId: '10000',
          compId: 'org',
          multiForm: null,
          desType: '2',
          form: null,
          beanId: this.$store.state.indexPath.indexTap.value,
          desName: this.$store.state.indexPath.indexTap.title,
          description: '',
          desCode: this.$store.state.indexPath.indexTap.business,
          grid: null,
          pkid: this.pkid || null,
          buttons: null,
          serviceName: null,
          attributes: []
        }
        this.converForm(conf)
      })
    },
    //  将最后处理完的数据提交
    saveMaster (conf) {
      this.$store.dispatch('saveTotle', conf).then(res => {
        this.pkid = !this.pkid ? res.data : this.pkid
        this.$notify.success('保存成功')
        this.$forceUpdate()
      }).catch(err => {
        this.$notify.error('保存失败')
        console.log(err)
      })
    },
    saveForm () {
      this.converConfig()
    },
    preView () {
      console.log(123)
    }
  },
  mounted () {
    if (this.load === 'mkdir') {
      this.newForm.visible = true
    }
  },
  created () {
    //  请求所有业务对象的数据
    this.$store.dispatch('getAllBean', {compId: 'org', userToken: 'admin'}).then(res => {
      if (res.status >= 200 || res.status <= 300) {
        this.newForm.options = res.data
      }
    }).catch(err => {
      return new Error(err)
    })
    this.$store.dispatch('fetchTmpls', {queryName: 'queryList', userToken: 'admin'}).then(res => {
      if (!Array.isArray(res.data) || !res.data.length) {
        this.hasTmpls = false
      } else {
        this.businessList = []
        for (let v of res.data) this.businessList.push(v)
        this.hasTmpls = true
        this.$forceUpdate()
      }
    }).catch(err => {
      return new Error(err)
    })
  },
  components: {
    edit,
    nonce
  },
  props: {
    move: {
      type: String
    },
    load: {
      type: String
    }
  }
}
</script>

<style lang="stylus">
.el-tabs__header
  margin-bottom: 3px
  .el-tabs__item
    user-select: none
#box
  width: 100%
  .el-radio-group
    display: grid
    grid-template-columns: 1fr 1fr 1fr 1fr
    grid-template-rows: 1fr
    justify-items: center
    justify-content: space-between
    & > label
      margin: 0
      align-self: center
      flex: 1
      display: inline-flex
      align-items: center
      min-height: 28px
  .save
    position: fixed
    bottom: 0
    margin: 0 auto
    left: 16.666%
    right: 25%
    height: 2.4rem
    box-sizing: border-box
    display: flex
    justify-content: flex-end
    align-items: center
    padding: 0.2rem
    box-shadow: 0px 0px 4px 2px rgba(134, 150, 255, 0.7)
    z-index: 1
    background-color: #fff
    transform-origin: 50% 50% 50%
    .el-button
      width: 7.5rem
      &:hover
        transform: translate(0, -2px)
        box-shadow: 0px 2px 4px 2px #999
</style>
